package priv.bestbeat.cloud.generator;


import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import org.apache.commons.lang3.StringUtils;
import org.yaml.snakeyaml.Yaml;

import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
* @author 张渠钦
* @date 2021/5/24 18:16
*/
public class CodeGenerator {

    private static final String PROJECT_PATH = "./mybatis-plus-autoGenerator";

    /**
    * 全局配置
    * @return
    */
    public static GlobalConfig globalConfig() {
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(PROJECT_PATH + "/src/main/resources/generated-files");
        globalConfig.setAuthor("system");
        globalConfig.setOpen(false);
        return globalConfig;
    }

    /**
    * 数据源配置
    * @return
    */
    public static DataSourceConfig dataSourceConfig(String dbName) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(PROJECT_PATH+"/src/main/resources/config.yml");
        Yaml yaml = new Yaml();
        ConfigProperties configProperties = yaml.loadAs(fileInputStream,ConfigProperties.class);

        DatasourceProperties properties = configProperties.getDatasource().get(dbName.trim());

        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl(properties.getUrl());
        dataSourceConfig.setDriverName(properties.getDriverName());
        dataSourceConfig.setUsername(properties.getUsername());
        dataSourceConfig.setPassword(properties.getPassword());
        return dataSourceConfig;
    }

    /**
    * 包设置
    * @return
    */
    public static PackageConfig packageConfig() {
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(scanner("功能模块名"));
        packageConfig.setParent("");
        return packageConfig;
    }

    /**
     * 配置模板
     * @return
     */
    public static TemplateConfig templateConfig() {
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setController("templates/controller.java");
        templateConfig.setService("templates/service.java");
        templateConfig.setServiceImpl("templates/serviceImpl.java");
        // 清除默认生成方式
        templateConfig.setEntity(null);
        // 清除默认生成方式
        templateConfig.setMapper(null);
        // 清除默认生成方式
        templateConfig.setXml(null);
        return templateConfig;
    }

    /**
     * 策略配置
     * @return
     */
    public static StrategyConfig strategyConfig() {
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setEntityLombokModel(true);
        strategyConfig.setRestControllerStyle(true);
        strategyConfig.setTablePrefix("t_","T_");
        return strategyConfig;
    }

    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ": ");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNoneBlank(ipt.trim())) {
                return ipt.trim();
            }
        }
        throw new MybatisPlusException();
    }

    public static void main(String[] args) throws IOException {
        // 代码生成器
        AutoGenerator autoGenerator = new AutoGenerator();

        // 全局配置
        autoGenerator.setGlobalConfig(globalConfig());

        String dbName = scanner("数据库名");
        // 数据源配置
        autoGenerator.setDataSource(dataSourceConfig(dbName));

        // 包配置
        autoGenerator.setPackageInfo(packageConfig());

        //自定义参数
        final Map<String,Object> map = new HashMap<>();
        map.put("projectName",scanner("归属的项目模块"));
        String className = scanner("类名（需要大写开头）");
        String varName = className.substring(0,1).toLowerCase() + className.substring(1);
        map.put("className",className);
        map.put("varName",varName);
        map.put("tableName",scanner("表名（全称）"));
        map.put("author",autoGenerator.getGlobalConfig().getAuthor());
        map.put("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {

                this.setMap(map);
            }
        };

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        // mapper xml 自定义
        focList.add(new FileOutConfig("templates/mapper.xml.vm") {
            // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
            @Override
            public String outputFile(TableInfo tableInfo) {
                return  PROJECT_PATH + "/src/main/resources/mapper/" + autoGenerator.getPackageInfo().getModuleName()
                        + "/" + varName + "Mapper" + StringPool.DOT_XML;
            }
        });

        // mapper java 自定义
        focList.add(new FileOutConfig("templates/mapper.java.vm") {
            // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
            @Override
            public String outputFile(TableInfo tableInfo) {
                return  PROJECT_PATH + "/src/main/resources/generated-files/" + autoGenerator.getPackageInfo().getModuleName()
                        + "/mapper/I" + className + "Mapper" + StringPool.DOT_JAVA;
            }
        });

        // entity 自定义
        focList.add(new FileOutConfig("templates/entity.java.vm") {
            // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
            @Override
            public String outputFile(TableInfo tableInfo) {
                return  PROJECT_PATH + "/src/main/resources/generated-files/" + autoGenerator.getPackageInfo().getModuleName()
                        + "/entity/" + className + "Entity" + StringPool.DOT_JAVA;
            }
        });

        cfg.setFileOutConfigList(focList);
        autoGenerator.setCfg(cfg);

        // 配置模板
        autoGenerator.setTemplate(templateConfig());

        // 策略配置
        autoGenerator.setStrategy(strategyConfig());

        autoGenerator.setTemplateEngine(new VelocityTemplateEngine());
        autoGenerator.execute();

    }
}
